home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / lib / c / etc / RCS / popen.c,v < prev    next >
Text File  |  1991-05-29  |  3KB  |  199 lines

  1. head     1.4;
  2. branch   ;
  3. access   ;
  4. symbols  ;
  5. locks    ; strict;
  6. comment  @ * @;
  7.  
  8.  
  9. 1.4
  10. date     91.05.28.23.07.39;  author jhh;  state Exp;
  11. branches ;
  12. next     1.3;
  13.  
  14. 1.3
  15. date     88.07.29.17.49.52;  author ouster;  state Exp;
  16. branches ;
  17. next     1.2;
  18.  
  19. 1.2
  20. date     88.07.28.17.48.05;  author ouster;  state Exp;
  21. branches ;
  22. next     1.1;
  23.  
  24. 1.1
  25. date     88.07.11.10.57.20;  author ouster;  state Exp;
  26. branches ;
  27. next     ;
  28.  
  29.  
  30. desc
  31. @@
  32.  
  33.  
  34. 1.4
  35. log
  36. @children were lost if they exited while you where waiting for a
  37. different child
  38. @
  39. text
  40. @/*
  41.  * Copyright (c) 1980 Regents of the University of California.
  42.  * All rights reserved.  The Berkeley software License Agreement
  43.  * specifies the terms and conditions for redistribution.
  44.  */
  45.  
  46. #if defined(LIBC_SCCS) && !defined(lint)
  47. static char sccsid[] = "@@(#)popen.c    5.5 (Berkeley) 9/30/87";
  48. #endif LIBC_SCCS and not lint
  49.  
  50. #include <stdio.h>
  51. #include <signal.h>
  52. #include <sys/wait.h>
  53.  
  54. #define    tst(a,b)    (*mode == 'r'? (b) : (a))
  55. #define    RDR    0
  56. #define    WTR    1
  57.  
  58. extern    char *malloc();
  59.  
  60. static    int *popen_pid;
  61. static    int nfiles;
  62. static    int *child_status;
  63.  
  64.  
  65. FILE *
  66. popen(cmd,mode)
  67.     char *cmd;
  68.     char *mode;
  69. {
  70.     int p[2];
  71.     int myside, hisside, pid;
  72.  
  73.     if (nfiles <= 0)
  74.         nfiles = getdtablesize();
  75.     if (popen_pid == NULL) {
  76.         popen_pid = (int *)malloc((unsigned)
  77.             (nfiles * sizeof *popen_pid));
  78.         if (popen_pid == NULL)
  79.             return (NULL);
  80.         child_status = (int *)malloc((unsigned)
  81.             (nfiles * sizeof *child_status));
  82.         if (child_status == NULL)
  83.             return (NULL);
  84.         for (pid = 0; pid < nfiles; pid++) {
  85.             popen_pid[pid] = -1;
  86.             child_status[pid] = -1;
  87.         }
  88.     }
  89.     if (pipe(p) < 0)
  90.         return (NULL);
  91.     myside = tst(p[WTR], p[RDR]);
  92.     hisside = tst(p[RDR], p[WTR]);
  93.     if ((pid = vfork()) == 0) {
  94.         /* myside and hisside reverse roles in child */
  95.         close(myside);
  96.         if (hisside != tst(0, 1)) {
  97.             dup2(hisside, tst(0, 1));
  98.             close(hisside);
  99.         }
  100.         execl("/bin/sh", "sh", "-c", cmd, (char *)NULL);
  101.         _exit(127);
  102.     }
  103.     if (pid == -1) {
  104.         close(myside);
  105.         close(hisside);
  106.         return (NULL);
  107.     }
  108.     popen_pid[myside] = pid;
  109.     close(hisside);
  110.     return (fdopen(myside, mode));
  111. }
  112.  
  113. pclose(ptr)
  114.     FILE *ptr;
  115. {
  116.     int omask;
  117.     int child, pid, status;
  118.     int i;
  119.     int file;
  120.  
  121.     file = fileno(ptr);
  122.     if (popen_pid != NULL) {
  123.         child = popen_pid[file];
  124.         popen_pid[file] = -1;
  125.     } else {
  126.         child = -1;
  127.     }
  128.     fclose(ptr);
  129.     if (child == -1)
  130.         return (-1);
  131.     if (child_status[file] != -1) {
  132.         status = child_status[file];
  133.         child_status[file] = -1;
  134.         return (status);
  135.     }
  136.     omask = sigblock(sigmask(SIGINT)|sigmask(SIGQUIT)|sigmask(SIGHUP));
  137.     while ((pid = wait((union wait *) &status)) != child && pid != -1) {
  138.         for (i = 0; i < nfiles; i++) {
  139.         if (popen_pid[i] == pid) { 
  140.             child_status[i] = status;
  141.             break;
  142.         }
  143.         }
  144.     }
  145.     (void) sigsetmask(omask);
  146.     return (pid == -1 ? -1 : status);
  147. }
  148. @
  149.  
  150.  
  151. 1.3
  152. log
  153. @Lint.
  154. @
  155. text
  156. @d23 1
  157. d25 1
  158. d41 5
  159. a45 1
  160.         for (pid = 0; pid < nfiles; pid++)
  161. d47 2
  162. d79 2
  163. d82 7
  164. a88 2
  165.     child = popen_pid[fileno(ptr)];
  166.     popen_pid[fileno(ptr)] = -1;
  167. d92 5
  168. d98 8
  169. a105 2
  170.     while ((pid = wait((union wait *) &status)) != child && pid != -1)
  171.         ;
  172. @
  173.  
  174.  
  175. 1.2
  176. log
  177. @Lint.
  178. @
  179. text
  180. @d13 1
  181. @
  182.  
  183.  
  184. 1.1
  185. log
  186. @Initial revision
  187. @
  188. text
  189. @d34 2
  190. a35 1
  191.         popen_pid = (int *)malloc(nfiles * sizeof *popen_pid);
  192. d68 1
  193. a68 1
  194.     long omask;
  195. d77 1
  196. a77 1
  197.     while ((pid = wait(&status)) != child && pid != -1)
  198. @
  199.